package com.citrix.gs.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.citrix.gs.util.base.PerforceUtil;
import com.citrix.gs.util.beacon.BeaconCI;
import com.citrix.gs.util.beacon.ToolType;
import com.citrix.gs.util.common.CIInfo;
import com.citrix.gs.util.common.CIType;
import com.citrix.gs.util.common.Config;
import com.offbytwo.jenkins.model.Job;
import com.perforce.p4java.core.file.FileSpecBuilder;
import com.perforce.p4java.core.file.FileSpecOpStatus;
import com.perforce.p4java.core.file.IFileSpec;
import com.perforce.p4java.exception.P4JavaException;
import com.perforce.p4java.option.server.GetDepotFilesOptions;

/*
 * Trigger jobs after a tool updated to new revision */
public class ToolUpdater extends PerforceUtil {
    
    private static Logger logger = LoggerFactory.getLogger(ToolUpdater.class);
    
    private ToolType toolType;
    private CIInfo ciInfo;
    private BeaconCI ci;
    private String toolPath;
    
    public ToolUpdater(ToolType toolType, CIInfo ciInfo) {
        super();
        
        this.toolType = toolType;
        this.ciInfo = ciInfo;
        this.ci = new BeaconCI(ciInfo);
        
        this.toolPath = (ciInfo.getType() == CIType.prod? Config.me().getProdToolDir() : Config.me().getTestToolDir()) + "/" + toolType.name() + "/...";
        
        super.initConfigServer();
    }
    
    private Date getUpdatedDate(){
        
        try {
            List<IFileSpec> fileList = perforceServer.getDepotFiles(
                    FileSpecBuilder.makeFileSpecList(toolPath), new GetDepotFilesOptions());
            
            if(fileList != null) {
                return fileList.stream().filter(f -> f.getOpStatus() == FileSpecOpStatus.VALID)
                .map(f -> f.getDate())
                .reduce((d1, d2) -> d1.getTime() > d2.getTime() ? d1 : d2).get();
            }
            
            
        } catch (P4JavaException e) {
            logger.error("Get tool updated data fail: ", e);
        }
        
        return null;
    }
    
    public void apply() {
        logger.info("Apply latest {} to {}", toolType, ciInfo);
        
        // Check tool update date
        Date updatedDate = getUpdatedDate();
        
        DateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
        ft.setTimeZone(TimeZone.getTimeZone("GMT"));
        
        logger.info("Tool updated time: {}", ft.format(updatedDate));
        
        ci.runTopJobs(ci.getViewJobs(toolType.name(), updatedDate));
        
        releaseConfigServer();
    }
    

    public static void main(String[] args) {

        ToolUpdater tu = new ToolUpdater(ToolType.ResourceDetector, Config.me().getProdCI());
        tu.apply(); 
    }

}
